package org.myapp.datastore;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.mortbay.log.Log;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.PreparedQuery.TooManyResultsException;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

/**
 * LowLevel Queryクラス.<br>
 *
 * @author Administrator
 *
 */
public class AutoQuery {

    private Query query;
    private FetchOptions fetchOptions = null;

    public AutoQuery(String kind) {
        query = new Query(kind);
    }

    public AutoQuery eq(String key, Object value) {
        query.addFilter(key, FilterOperator.EQUAL, value);
        return this;
    }

    public AutoQuery lt(String key, Object value) {
        query.addFilter(key, FilterOperator.LESS_THAN, value);
        return this;
    }

    public AutoQuery le(String key, Object value) {
        query.addFilter(key, FilterOperator.LESS_THAN_OR_EQUAL, value);
        return this;
    }

    public AutoQuery gt(String key, Object value) {
        query.addFilter(key, FilterOperator.GREATER_THAN, value);
        return this;
    }

    public AutoQuery ge(String key, Object value) {
        query.addFilter(key, FilterOperator.GREATER_THAN_OR_EQUAL, value);
        return this;
    }

    public AutoQuery limit(int limit) {
        if (fetchOptions == null) {
            fetchOptions = FetchOptions.Builder.withLimit(limit);
        } else {
            fetchOptions.limit(limit);
        }
        return this;
    }

    public AutoQuery offset(int offset) {
        if (fetchOptions == null) {
            fetchOptions = FetchOptions.Builder.withOffset(offset);
        } else {
            fetchOptions.offset(offset);
        }
        return this;
    }

    public AutoQuery asc(String key) {
        query = query.addSort(key, Query.SortDirection.ASCENDING);
        return this;
    }
    public AutoQuery desc(String key) {
        query = query.addSort(key, Query.SortDirection.DESCENDING);
        return this;
    }

    public Entity asSingle() {
        try {
            return Store.get().prepare(query).asSingleEntity();
        } catch (TooManyResultsException tmre) {
            Log.debug(tmre);
        }
        return null;
    }

    public List<Entity> asList() {

        PreparedQuery q = Store.get().prepare(query);

        Iterator<Entity> it = null;
        if (fetchOptions == null) {
            it = q.asIterator();
        } else {
            it = q.asIterator(fetchOptions);
        }

        List<Entity> results = new ArrayList<Entity>();
        while (it.hasNext()) {
            results.add(it.next());
        }
        return results;
    }
}
